package cn.com.utils;

import cn.com.bean.IdDto;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;
import java.util.TreeSet;
import java.util.stream.Collectors;

@Slf4j
public class FileUtil {
    public static final String FILE_NAME = "tag.txt";
    public static final int HISTORICAL_SIZE = 20;
    public static final String DEFAULT_BRANCH_TXT = "defaultBranch.txt";
    public static final String WEBSITE_TXT = "website.txt";
    public static final String ID_TXT = "id.txt";
    public static final String CONFIGURATION_FILE = "application.txt";
    public static final String REGEX = "=";

    /**
     * 输出阶段名称
     *
     * @param tagName 标记名称
     * @throws IOException IOException
     */
    public static void outputTageName(String tagName) throws IOException {
        try (BufferedWriter writer = new BufferedWriter(new FileWriter(FILE_NAME, true))) {
            writer.write(tagName);
            writer.newLine();
            writer.flush();
        }
    }

    //查询
    public static List<IdDto> query() {
        List<String> id = null;
        try {
            id = Optional.of(Files.readAllLines(Paths.get(ID_TXT))).orElse(new ArrayList<>());
        } catch (IOException e) {
            System.out.println(e.getMessage());
        }
        return id.stream().map(e -> ObjectMapperUtils.readValue(e, IdDto.class)).collect(Collectors.toList());
    }

    /**
     * 保存
     *
     * @param idDtos id dtos
     * @throws IOException IOException
     */
    public static void save(List<IdDto> idDtos) {
        try (BufferedWriter writer = new BufferedWriter(new FileWriter(ID_TXT, true))) {
            for (IdDto idDto : idDtos) {
                idDto.setDescription("");
                writer.write(ObjectMapperUtils.writeValueAsString(idDto));
                writer.newLine();
            }
            writer.flush();
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }


    /**
     * 更新
     *
     * @param idDtos id dtos
     * @throws IOException IOException
     */
    public static void update(List<IdDto> idDtos) {
        try (BufferedWriter writer = new BufferedWriter(new FileWriter(ID_TXT))) {
            for (IdDto idDto : idDtos) {
                idDto.setDescription("");
                writer.write(ObjectMapperUtils.writeValueAsString(idDto));

                writer.newLine();
            }
            writer.flush();
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }

    /**
     * 输入标记名
     *
     * @param tagList 标记列表
     * @throws IOException IOException
     */
    public static void inputTagName(Set<String> tagList) throws IOException {
        try (BufferedReader reader = new BufferedReader(new FileReader(FILE_NAME))) {
            String line;
            while ((line = reader.readLine()) != null) {
                tagList.add(line);
            }
        }
        if (tagList.size() > HISTORICAL_SIZE) {
            try (BufferedWriter writer = new BufferedWriter(new FileWriter("tag-旧历史数据.txt", true))) {
                tagList.forEach(line -> {
                    try {
                        writer.write(line);
                        writer.newLine();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                });

                writer.flush();
            }
            clearFileContent(FILE_NAME);
        }
    }

    /**
     * 创建文件（如果不存在）
     *
     * @throws IOException IOException
     */
    public static void createFileIfNotExists() {
        createFileIfNotExists(FILE_NAME);
        createFileIfNotExists(CONFIGURATION_FILE);
        createFileIfNotExists(DEFAULT_BRANCH_TXT);
        createFileIfNotExists(ID_TXT);
    }

    /**
     * 创建文件（如果不存在）
     *
     * @throws IOException IOException
     */
    public static void createFileIfNotExists(String name) {
        try {
            Files.createFile(Paths.get(name));
        } catch (Exception e) {
            // 文件已存在，无需创建
        }

    }

    /**
     * 获取分支名称
     *
     * @return {@link String}
     * @throws IOException IOException
     */
    public static String getBranchName() throws IOException {
        List<String> value = Files.readAllLines(Paths.get(DEFAULT_BRANCH_TXT));
        return CollectionUtil.isEmpty(value) ? "release-dev2.6.0" : value.get(0);
    }

    /**
     * 从文件读取字节
     *
     * @param filePath 文件路径
     * @return {@link byte[]}
     */
    public static byte[] readBytesFromFile(String filePath) {
        FileInputStream fileInputStream = null;
        byte[] bytesArray = null;

        try {
            File file = new File(filePath);
            bytesArray = new byte[(int) file.length()];
            fileInputStream = new FileInputStream(file);
            fileInputStream.read(bytesArray);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (fileInputStream != null) {
                try {
                    fileInputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

        return bytesArray;
    }


    /**
     * 获取env变量
     *
     * @return {@link String}
     * @throws IOException IOException
     */
    public static String getEnv(String key) {
        List<String> value = null;
        try {
            value = Files.readAllLines(Paths.get(CONFIGURATION_FILE));
            return CollectionUtil.isEmpty(value) ? "" : value.stream().filter(e -> {
                String[] split = e.split(REGEX);
                return split.length > 1 && split[0].equals(key);
            }).map(e -> {
                String[] split = e.split(REGEX);
                return split.length > 2 ? split[1] : "";
            }).findFirst().orElse("");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }

    }

    /**
     * 阅读所有行
     *
     * @param first 第一
     * @return {@link List }<{@link String }>
     * @throws IOException IOException
     */
    public static List<String> getReadAllLines(String first) {
        try {
            return Files.readAllLines(Paths.get(first));
        } catch (Exception e) {
            log.error("读取文件失败", e);
            return new ArrayList<>();
        }
    }

    /**
     * 写入文件
     *
     * @param content  内容
     * @param filePath 文件路径
     */
    public static void writeToFile(Map<String, String> content, String filePath) {
        if (CollUtil.isEmpty(content)) {
            return;
        }
        StringBuilder sb = new StringBuilder();
        content.forEach((k, v) -> sb.append(k).append("=").append(v).append("\n"));
        writeToFile(sb.toString(), filePath);
    }

    /**
     * 写入文件
     *
     * @param content  内容
     * @param filePath 文件路径
     */
    public static void writeToFile(Collection<String> content, String filePath) {
        if (CollUtil.isEmpty(content)) {
            return;
        }
        StringBuilder sb = new StringBuilder();
        content.forEach(e -> sb.append(e).append("\n"));
        writeToFile(sb.toString(), filePath);
    }

    /**
     * 写入文件
     *
     * @param content  内容
     * @param filePath 文件路径
     */
    public static void writeToFile(StringBuilder content, String filePath) {
        if (StrUtil.isBlank(content)) {
            return;
        }
        writeToFile(content.toString(), filePath);
    }

    /**
     * 写入文件
     *
     * @param content  内容
     * @param filePath 文件路径
     */
    public static void writeToFile(String content, String filePath) {
        try {
            Files.write(Paths.get(filePath), content.getBytes(StandardCharsets.UTF_8));
        } catch (IOException e) {
            log.error("写入文件失败", e);
        }
    }

    /**
     * 获取接口文件名
     *
     * @param directoryPath 目录路径
     * @param fileType      文件类型
     * @return {@link Set}<{@link String }>
     */
    public static Set<String> getFileName(String directoryPath, String fileType) {
        Set<String> fileNames = new TreeSet<>();
        File directory = new File(directoryPath);

        // 使用匿名内部类作为文件名过滤器
        File[] harFiles = directory.listFiles((dir, name) -> name.endsWith("." + fileType));

        if (harFiles != null) {
            for (File file : harFiles) {
                String fileName = file.getName();
                fileNames.add(fileName);
            }
        } else {
            System.out.println("提供的路径不是一个目录，或者目录是空的。");
        }
        return fileNames;
    }

    /**
     * 获取网站
     *
     * @return {@link String}
     * @throws IOException IOException
     */
    public static List<String> getWebsite() throws IOException {
        List<String> value = Files.readAllLines(Paths.get(WEBSITE_TXT));
        return CollectionUtil.isEmpty(value) ? new ArrayList<>() : value;
    }

    /**
     * 清除文件内容
     *
     * @param filePath 文件路径
     * @throws IOException IOException
     */
    public static void clearFileContent(String filePath) throws IOException {
        Path path = Paths.get(filePath);
        // 清空文件内容
        Files.write(path, new byte[0]);

        System.out.println("文件内容已清空：" + filePath);
    }

    /**
     * 写入文件
     *
     * @param str            str
     * @param outputFilePath 输出文件路径
     * @throws IOException IOException
     */
    public static void write(String str, String outputFilePath) throws IOException {
        Files.write(Paths.get(outputFilePath), str.getBytes(StandardCharsets.UTF_8));
    }
}
